package kr.ac.kookmin.cs.random;

import java.math.BigInteger;
import java.util.Random;

import kr.ac.kookmin.cs.randomtest.RandomNumberSequenceGenerator;

public class BlumBlumShup extends RandomNumberSequenceGenerator {
	
	private BigInteger p = null;
	private BigInteger q = null;
	private BigInteger m = null;
	
	private BigInteger next = null;
	private BigInteger x = null;
	
	public BlumBlumShup(){
		super();
		this.p = BigInteger.probablePrime(32, new Random(1));
		this.q = BigInteger.probablePrime(32, new Random(2));
		m = p.multiply(q);
	}
	
	public void initialize(long seed){
		super.initialize(seed);
		next = new BigInteger(Long.toString(seed));
	}
	
	@Override
	protected long getNextRandomNumber() {
		
		long result = 0x0L;
		
		for(int i = 0 ; i < 32 ; i++){
			
			BigInteger tmp = getNext();
			if((tmp.intValue() & 0x1) == 1){
				result |= 0x00000001L;
			}

			if(i != 31)
				result <<= 1;
			
		}
		
		return result;
	}

	@Override
	protected long getRandomNumberWithSeed(long seed) {
		
		initialize(seed);
		
		return getNextRandomNumber();
	}
	
	
	private BigInteger getNext(){
		
		x = next;
		
		BigInteger result = x.multiply(x).mod(m);
		
		next = result;
		
		return result;
	}
	
	
	
	public static void main(String[] args){
		
		BlumBlumShup bbs = new BlumBlumShup();
		
		bbs.initialize(1);
		
	}

}
